/*
 *   Copyright©2023 JoyCastle.
 *   All Rights Reserved.
 *   
 *   FileName:     CityModelManager.cs
 *   Author:       Administrator
 *   CreateTime:   2024/01/22 14:49:02
 *   UnityVersion: 2020.3.48f1c1
 *   Version:      1.1.3
 *   Description:
 *   
 */

using System;
using System.Collections;
using System.Collections.Generic;
using MotionFramework;
using MotionFramework.Window;
using UnityEngine;

public class CityModelManager:ModuleSingleton<CityModelManager>,IModule
{
    private readonly List<ModelObject> _stack = new List<ModelObject>(20);

    /// <summary>
    /// 反射服务接口
    /// </summary>
    public IActivatorServices ActivatorServices { get; set; }
    
    void IModule.OnCreate(object createParam)
    {
    }	
    void IModule.OnUpdate()
    {
        int count = _stack.Count;
        for (int i = 0; i < _stack.Count; i++)
        {
	        if (_stack.Count != count)
	        {
		        break;
	        }
            ModelObject model = _stack[i];
            if (model.IsPrepare)
            {
	            model.InternalUpdate();
            }
        }
    }
    void IModule.OnGUI()
    {
        //ConsoleGUI.Lable($"[{nameof(ModelManager)}] Model total count : {_stack.Count}");
    }
    
    /// <summary>
    /// 是否有任意窗口正在加载
    /// </summary>
    public bool IsLoading()
    {
        for (int i = 0; i < _stack.Count; i++)
        {
            ModelObject model = _stack[i];
            if (model.IsDone == false)
            {
	            return true;
            }
        }
        return false;
    }
    
    /// <summary>
    /// 检测窗口是否加载完毕
    /// </summary>
    public bool IsLoadDone<T>()
    {
        return IsLoadDone(typeof(T));
    }
    public bool IsLoadDone(Type type)
    {
        ModelObject model = GetModel(type.FullName);
        if (model == null)
        {
	        return false;
        }
        return model.IsDone;
    }
    
    /// <summary>
    /// 打开窗口
    /// </summary>
    /// <param name="location">资源路径</param>
    /// <param name="userData">用户数据</param>
    public ModelObject LoadModel<T>(string modelName,string location, System.Object userData = null) where T : ModelObject
    {
        return LoadModel(typeof(T),modelName, location, userData);
    }
    
    public ModelObject LoadModel(Type type,string name, string location, System.Object userData = null)
    {
        string modelName = name;

        // 如果窗口已经存在
        if (IsContains(modelName))
        {
	        ModelObject model = GetModel(modelName);
            Pop(model); //弹出窗口
            Push(model); //重新压入
            model.TryInvoke(OnModelPrepare, userData);
            return model;
        }
        else
        {
	        ModelObject model = CreateInstance(type,modelName);
            Push(model); //首次压入
            model.InternalLoad(location, OnModelPrepare, userData);
            return model;
        }
    }
    
    /// <summary>
    /// 关闭窗口
    /// </summary>
    public void RemoveModel(string name)
    {
	    string modelName = name;
	    ModelObject model = GetModel(modelName);
	    if (model == null)
	    {
		    return;
	    }

	    model.InternalDestroy();
	    Pop(model);
	    model.Go.gameObject.SetActive(false);
    }
    
    /// <summary>
    /// 关闭所有窗口
    /// </summary>
    public void RemoveAll()
    {
        for (int i = 0; i < _stack.Count; i++)
        {
	        ModelObject model = _stack[i];
	        model.InternalDestroy();
        }
        _stack.Clear();
    }
    
    /// <summary>
    /// 获取当前打开的所有窗口
    /// </summary>
    public List<ModelObject> GetAllOpenedModel()
    {
        return _stack;
    }

    private void OnModelPrepare(ModelObject model)
    {
	    model.InternalCreate();
	    model.InternalRefresh();

	    model.Go.gameObject.SetActive(true);
    }
    
	private ModelObject CreateInstance(Type type,string modelName)
	{
		ModelObject model;
		if (ActivatorServices != null)
		{
			model = ActivatorServices.CreateInstance(type) as ModelObject;
		}
		else
		{
			model = Activator.CreateInstance(type) as ModelObject;
		}

		if (model == null)
		{
			throw new Exception($"model {type.FullName} create instance failed.");
		}
		
		model.Init(modelName);
		return model;
	}
	private ModelObject GetModel(string name)
	{
		for (int i = 0; i < _stack.Count; i++)
		{
			ModelObject model = _stack[i];
			if (model.ObjectName == name)
			{
				return model;
			}
		}
		return null;
	}

	public ModelObject GetModelByName(string name)
	{
		return GetModel(name);
	}

	private bool IsContains(string name)
	{
		for (int i = 0; i < _stack.Count; i++)
		{
			ModelObject model = _stack[i];
			if (model.ObjectName == name)
			{
				return true;
			}
		}
		return false;
	}
	private void Push(ModelObject model)
	{
		// 如果已经存在
		if (IsContains(model.ObjectName))
		{
			throw new System.Exception($"Model {model.ObjectName} is exist.");
		}
			
		// 最后插入到堆栈
		_stack.Add(model);
	}
	private void Pop(ModelObject model)
	{
		// 从堆栈里移除
		_stack.Remove(model);
	}
}

